using System;
using System.Collections.Generic;
using foundation;

public class O1Transfrom
{
    Dictionary<Type, IO1Transfrom> transfromTable = new Dictionary<Type, IO1Transfrom>();

    public O1Transfrom()
    {
        var normal = new O1NormalValue();
        transfromTable.Add(typeof(System.SByte), normal);
        transfromTable.Add(typeof(System.Byte), normal);
        transfromTable.Add(typeof(System.Int16), normal);
        transfromTable.Add(typeof(System.UInt16), normal);
        transfromTable.Add(typeof(System.Int32), normal);
        transfromTable.Add(typeof(System.UInt32), normal);
        transfromTable.Add(typeof(System.Int64), normal);
        transfromTable.Add(typeof(System.UInt64), normal);
        transfromTable.Add(typeof(System.Single), normal);
        transfromTable.Add(typeof(System.Double), normal);
        transfromTable.Add(typeof(System.Decimal), normal);
        transfromTable.Add(typeof(string), normal);
        transfromTable.Add(typeof(bool), normal);


        transfromTable.Add(typeof(List<>), new O1ListValue());
        transfromTable.Add(typeof(ASObject), new O1AsObjectValue());

        transfromTable.Add(typeof(CodeFunctionVO), new O1Func());
        transfromTable.Add(typeof(CodePropertyVO), new O1Property());
        transfromTable.Add(typeof(CodeCalcVO), new O1Calc());
    }


    public object exec(object root, object property)
    {

        IO1Transfrom table = null;

        transfromTable.TryGetValue(property.GetType(), out table);

        if (null != table)
        {
            return table.exec(root, property);
        }


        return property;
    }
}


class O1NormalValue : IO1Transfrom
{
    public object exec(object root, object property)
    {
        return property;
    }
}


class O1ListValue : IO1Transfrom
{
    public object exec(object root, object property)
    {
        object[] value = (object[])property;
        object[] result = new object[value.Length];
        for (int i = 0; i < value.Length; i++)
        {
            result[i] = O1Exec.codeDoProperty(root, value[i]);
        }
        return result;
    }
}

class O1AsObjectValue : IO1Transfrom
{
    public object exec(object root, object property)
    {
        ASObject result = new ASObject();
        foreach (KeyValuePair<string, object> entry in (Dictionary<string, object>)property)
        {
            result[entry.Key] = O1Exec.codeDoProperty(root, entry.Value);
        }
        return result;
    }
}